/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package b_and_b_properties.data;

import org.jdesktop.application.*;
import java.util.*;
import javax.persistence.*;
import org.jdesktop.beansbinding.*;

/**
 *
 * @author Omea
 * bN7Xn8ae2nH3
 */
public class DAO extends FrameView {

    public DAO(SingleFrameApplication app) {
        super(app);

        initComponents();
    }

    private void initComponents() {
        propertyList = new ArrayList<Property>();
        unitList = new ArrayList<Unit>();
        roomList = new ArrayList<Room>();
        appContext = Application.getInstance(b_and_b_properties.B_and_B_PropertiesApp.class).getContext();
        resourceMap = getResourceMap();
        openConnection();
    }

    public void openConnection() {
        entityManager = Persistence.createEntityManagerFactory("sapcapstonePU").createEntityManager(); // NOI18N
    }

    public void shutdown() {
        System.out.println("shutting down...");
        try {
            getEntityManager().getTransaction().commit();
            getEntityManager().close();
        } catch (RollbackException rex) {
            rex.printStackTrace();
            getEntityManager().getTransaction().begin();
            List<Property> merged = new ArrayList<Property>(propertyList.size());
            for (Property p : propertyList) {
                merged.add(getEntityManager().merge(p));
            }
            propertyList.clear();
            propertyList.addAll(merged);
        }
    }
// Property

    public Task saveProperty(Property property) {
        return new SaveTaskProperty(getApplication(), property);
    }

    private class SaveTaskProperty extends Task {

        private Property property;
        private EntityManager em;

        SaveTaskProperty(org.jdesktop.application.Application app, Property property) {
            super(app);
            System.out.println("new save property task");
            this.property = property;
            doInBackground();
        }

        @Override
        protected Void doInBackground() {
            System.out.println("save property background starting...");
            em = getEntityManager();
            try {
                em.getTransaction().begin();
                em.persist(property);
//                int propID = property.getIdproperty();
                doUnits();
//                propertyList.add(property);
                em.getTransaction().commit();
//                entityManager.getTransaction().begin();
            } catch (RollbackException rex) {
                rex.printStackTrace();
                getEntityManager().getTransaction().begin();
                List<Property> merged = new ArrayList<Property>(propertyList.size());
                for (Property p : propertyList) {
                    merged.add(getEntityManager().merge(p));
                }
                propertyList.clear();
                propertyList.addAll(merged);
            }
            return null;
        }

        @Override
        protected void finished() {
            System.out.println("save property finished!!!");
//            setSaveNeededProperty(false);
        }

        private void doUnits() {
            int cnt = 1;
            try {
                for (Unit u : property.getUnitListAsList()) {
                    u.setPropertyIdproperty(property);
                    u.setUnitid(cnt);
                    em.persist(u);
                    doRooms(u.getRoomListAsList(), u);
                    cnt++;
                }
            } catch (RollbackException rex) {
                throw rex;
            }
        }

        private void doRooms(List<Room> rooms, Unit u) {
            try {
                for (Room r : rooms) {
                    r.setUnitIdunit(u);
                    em.persist(r);
                }
            } catch (RollbackException rex) {
                throw rex;
            }
        }
    }

    public void deleteRecordProperty(Property property) {
        System.out.println("deleteRecordProperty");
        try {
            getEntityManager().remove(property);
        } catch (RollbackException rex) {
                rex.printStackTrace();
                getEntityManager().getTransaction().begin();
                List<Property> merged = new ArrayList<Property>(propertyList.size());
                for (Property p : propertyList) {
                    merged.add(getEntityManager().merge(p));
                }
                propertyList.clear();
                propertyList.addAll(merged);
        }
    }

    /**
     * An example action method showing how to create asynchronous tasks
     * (running on background) and how to show their progress. Note the
     * artificial 'Thread.sleep' calls making the task long enough to see the
     * progress visualization - remove the sleeps for real application.
     */
    public Task refreshProperty() {
        return new RefreshTaskProperty(getApplication());
    }

    private class RefreshTaskProperty extends Task {

        RefreshTaskProperty(org.jdesktop.application.Application app) {
            super(app);
            System.out.println("new refresh task");
        }

        @SuppressWarnings("unchecked")
        @Override
        protected Void doInBackground() {
            System.out.println("refresh task in backgroung");
            try {
                setProgress(0, 0, 4);
                setMessage("Rolling back the current changes...");
                setProgress(1, 0, 4);
                getEntityManager().getTransaction().rollback();
                Thread.sleep(1000L); // remove for real app
                setProgress(2, 0, 4);

                setMessage("Starting a new transaction...");
                getEntityManager().getTransaction().begin();
                Thread.sleep(500L); // remove for real app
                setProgress(3, 0, 4);

                setMessage("Fetching new data...");
                // TODO fix query
//                java.util.Collection data = query.getResultList();
//                for (Object entity : data) {
//                    entityManager.refresh(entity);
//                }
                Thread.sleep(1300L); // remove for real app
                setProgress(4, 0, 4);

                Thread.sleep(150L); // remove for real app
                propertyList.clear();
                // TODO fix data
//                propertyList.addAll(data);
            } catch (InterruptedException ignore) {
            }
            return null;
        }

        @Override
        protected void finished() {
            setMessage("Done.");
//            setSaveNeededProperty(false);
        }
    }

    /**
     * @return the entityManager
     */
    public EntityManager getEntityManager() {
        return entityManager;
    }
    private EntityManager entityManager;
    private List<Property> propertyList;
    private List<Unit> unitList;
    private List<Room> roomList;
    private ResourceMap resourceMap;
    private ApplicationContext appContext;
}
